{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "768347ff",
   "metadata": {},
   "source": [
    "# 🌐 Macro‑Sentinel · Colab Notebook\n",
    "*Alpha‑Factory v1 👁️✨ — Cross‑asset macro risk radar*"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80e853b0",
   "metadata": {},
   "source": [
    "### Why this notebook?\n",
    "\n",
    "Run the full **Macro‑Sentinel** agent stack in <10 min without Docker.\n",
    "Ideal for quick experimentation, hackathons, classrooms, or due‑diligence.\n",
    "\n",
    "| Mode | LLM | Data feeds |\n",
    "|------|-----|------------|\n",
    "| **Offline** (default) | Mixtral‑8x7B (Ollama) | bundled CSV snapshots |\n",
    "| **Online**            | GPT‑4o (OpenAI)       | FRED API, Fed RSS, on‑chain flows |\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "541cda31",
   "metadata": {},
   "source": [
    "## 0 · Runtime check"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b91811d3",
   "metadata": {},
   "outputs": [],
   "source": [
    "!nvidia-smi -L || echo '🔹 GPU not detected — running on CPU'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9721caf1",
   "metadata": {},
   "source": [
    "## 1 · Clone repo & install Python deps\n",
    "*(≈ 90 s; wheels cached by Colab)*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b24b0e15",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "set -e\n",
    "if [ ! -d AGI-Alpha-Agent-v0 ]; then\n",
    "  git clone --depth 1 https://github.com/MontrealAI/AGI-Alpha-Agent-v0.git\n",
    "fi\n",
    "pip -q install -U openai_agents==0.2.4 gradio aiohttp psycopg2-binary                    qdrant-client rich pretty_errors                    ollama-py~=0.1.4\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef4ee381",
   "metadata": {},
   "source": [
    "### 🛜 Optional: pull Mixtral for offline mode (~4 GB)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "37d57f4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "python - <<'PY'\n",
    "import os, subprocess, json, shutil, pathlib, sys\n",
    "if not os.getenv(\"OPENAI_API_KEY\"):\n",
    "    try:\n",
    "        subprocess.run([\"ollama\", \"serve\"], check=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n",
    "        subprocess.run([\"ollama\", \"pull\", \"mixtral:instruct\"], check=True)\n",
    "    except FileNotFoundError:\n",
    "        print(\"⚠️ Ollama not found; offline LLM will not work.\")\n",
    "PY\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8a832ea8",
   "metadata": {},
   "source": [
    "## 2 · Configure credentials & runtime flags"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "482753a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os, getpass, json\n",
    "def _set(k,v):\n",
    "    if v is not None:\n",
    "        os.environ[k]=v\n",
    "\n",
    "_set('OPENAI_API_KEY', getpass.getpass('🔑 OpenAI key (blank for offline): '))\n",
    "_set('FRED_API_KEY',  '')\n",
    "_set('LIVE_FEED',     input('Real‑time feeds? (0/1) → ') or '0')\n",
    "os.environ['DEFAULT_PORTFOLIO_USD'] = '2000000'\n",
    "\n",
    "print(json.dumps({k:os.getenv(k,'') for k in ['OPENAI_API_KEY','FRED_API_KEY','LIVE_FEED']}, indent=2))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f8da8c5",
   "metadata": {},
   "source": [
    "## 3 · Launch Macro‑Sentinel dashboard"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2525ecb1",
   "metadata": {},
   "outputs": [],
   "source": [
    "import subprocess, re, pathlib, queue, threading, sys, time, textwrap, os\n",
    "root = pathlib.Path('AGI-Alpha-Agent-v0/alpha_factory_v1/demos/macro_sentinel')\n",
    "proc = subprocess.Popen([sys.executable, 'agent_macro_entrypoint.py'],\n",
    "                        cwd=root,\n",
    "                        stdout=subprocess.PIPE,\n",
    "                        stderr=subprocess.STDOUT,\n",
    "                        text=True, bufsize=1)\n",
    "\n",
    "link_q = queue.Queue()\n",
    "def _tail():\n",
    "    for line in proc.stdout:\n",
    "        print(line, end='')\n",
    "        m = re.search(r'(https://[\\w.-]+\\.gradio\\.live)', line)\n",
    "        if m: link_q.put(m.group(1))\n",
    "threading.Thread(target=_tail, daemon=True).start()\n",
    "\n",
    "print('⏳ Waiting for Gradio tunnel...')\n",
    "url = link_q.get()\n",
    "print(f'🎯 Open dashboard → {url}')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c0c5419c",
   "metadata": {},
   "source": [
    "## 4 · Programmatic agent call (optional)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e8dca393",
   "metadata": {},
   "outputs": [],
   "source": [
    "import asyncio, importlib, sys, json, pandas as pd\n",
    "sys.path.append('AGI-Alpha-Agent-v0/alpha_factory_v1/demos/macro_sentinel')\n",
    "import agent_macro_entrypoint as ms\n",
    "\n",
    "async def cycle():\n",
    "    evt  = await ms.macro_event()\n",
    "    risk = await ms.mc_risk(evt)\n",
    "    print('VaR 5 %:', risk['hedge']['metrics']['var'])\n",
    "    df = pd.DataFrame(risk['scenarios'])\n",
    "    return df\n",
    "await cycle()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "600e950a",
   "metadata": {},
   "source": [
    "## 5 · Chat over A2A protocol (bonus)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f18405c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "from google.a2a import AgentClient\n",
    "client = AgentClient(endpoint='http://localhost:7864/a2a')\n",
    "resp = client.chat({'query':'Summarize latest Fed speech & hedge suggestion'})\n",
    "print(resp['text'])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3374dbcf",
   "metadata": {},
   "source": [
    "## 6 · Graceful shutdown"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c8e0a4f3",
   "metadata": {},
   "outputs": [],
   "source": [
    "proc.terminate(); print('✅ Sentinel stopped')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c9f7bef",
   "metadata": {},
   "source": [
    "---\n",
    "© 2025 **MONTREAL.AI** • MIT License"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 5
}
